package com.mls.guardian.executor.master;

import com.mls.guardian.common.RemoteUtil;
import com.mls.guardian.container.MasterContainer;
import com.mls.guardian.dataobj.ServerProcessInfo;
import com.mls.guardian.protocol.RemoteBody;
import com.mls.guardian.protocol.RemoteCommand;
import com.mls.guardian.protocol.body.AppRestartBody;
import com.mls.guardian.remoting.executor.RemoteExecutor;
import io.netty.channel.ChannelHandlerContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.Future;

/**
 * Created by pengrenfang on 15/11/17.
 */
public class RestoreAppExecutor implements RemoteExecutor {
    private static final Logger log = LoggerFactory.getLogger(StopAppExecutor.class);
    private MasterContainer container;

    public RestoreAppExecutor(MasterContainer container) {
        this.container = container;
    }

    @Override
    public RemoteBody execute(ChannelHandlerContext ctx, RemoteCommand request) throws Exception {
        AppRestartBody response = new AppRestartBody();
        List<Future<RemoteBody>> futures = new ArrayList<>();

        AppRestartBody appRestore = (AppRestartBody) request.getRemoteBody();
        List<ServerProcessInfo> serverList = appRestore.getServerProcessInfoListList();

        List clientAddrs = new ArrayList();
        for (ServerProcessInfo serverInfo : serverList) {
            if (serverInfo.getIp().equals(RemoteUtil.getLocalHostIP())) {
                futures.add(container.getServiceExecutor().submit(new Callable<RemoteBody>() {
                    @Override
                    public RemoteBody call() throws Exception {
                        AppRestartBody appRestartBody = container.getAppController().restoreApp(appRestore.getProjectName(),appRestore.getVersionTag());
                        log.info("master 停止结束 返回");
                        return appRestartBody;
                    }
                }));
            } else {
                clientAddrs.add(serverInfo.getIp());
            }
        }

        List<Future<RemoteBody>> clientFutures = container.getClientDispatch().sendRequestToClientsByThreadPools(request, clientAddrs, -1, container.getServiceExecutor());
        futures.addAll(clientFutures);

        for (Future<RemoteBody> future : futures) {
            AppRestartBody responseFuture = (AppRestartBody) future.get();

            if (!responseFuture.isSuc()) {
                return responseFuture;
            }
        }

        response.setSuc(true);

        return response;
    }
}
